<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/7/21
 * Time: 12:28
 */

namespace common\service;

class Csv
{
    /**
     * 导出到本地
     * $option = [
     *      'models' => $bills,
     *      'fileName' => $this->yesterday() . "_{$this->businessType}",
     *      'columns' => array_keys($headerAttr),
     *      'headers' => $headerAttr,
     *      'savePath' => \Yii::$app->getBasePath() . $this->config['local_path'],
     *      'asAttachment' => false
     * ]
     * 直接导出由流量器下载
     * $option = [
     *      'models' => $bills,
     *      'fileName' => $this->yesterday() . "_{$this->businessType}",
     *      'columns' => array_keys($headerAttr),
     *      'headers' => $headerAttr,
     * ]
     * @param $option
     * @param bool $callback
     * @param bool $finish
     */
    public static function export($option, $callback = false, $finish = false)
    {
        set_time_limit(0);
        if (isset($option['savePath']) && isset($option['asAttachment']) && $option['asAttachment'] === false) {
            $filename = $option['savePath'] . $option['fileName'] . '.csv';
            $fp = fopen($filename, 'w');
            fputs($fp, $bom =(chr(0xEF) . chr(0xBB) . chr(0xBF)));
            fputcsv($fp, $option['headers']);
            foreach ($option['models'] as $row) {
                $temRow = [];
                foreach ($option['columns'] as $column) {
                    $temRow[$column] = $row[$column];
                }
                fputcsv($fp, $temRow);
            }
            fclose($fp);
        } else {
            $filename = $option['fileName'] . '.csv';
            header('Content-Description: File Transfer');
            header('Content-Type: application/vnd.ms-excel');
            header('Content-Disposition: attachment; filename="'. $filename .'"');
            header('Expires: 0');
            header('Cache-Control: must-revalidate');
            header('Pragma: public');

            $fp = fopen('php://output', 'a');//打开output流
            fputs($fp, $bom =(chr(0xEF) . chr(0xBB) . chr(0xBF)));
            fputcsv($fp, $option['headers']);//将数据格式化为CSV格式并写入到output流中

            $limit = 2000;
            $offset = 0;
            do {
                if ($finish) {
                    $data = $option['models']->all();
                } else {
                    $data = $option['models']->limit($limit)->offset($offset)->asArray()->all();
                }
                if ($callback instanceof \Closure) {
                    $callback($data);
                }
                $count = count($data);
                if ($finish){
                    foreach ($data as $row) {
                        $temRow = [];
                        foreach ($option['columns'] as $column) {
                            $temRow[$column] = $row[$column];
                        }
                        fputcsv($fp, $temRow);
                    }
                } else {
                    foreach ($data as $row) {
                        $temRow = [];
                        foreach ($option['columns'] as $column) {
                            $temRow[$column] = "\t" . $row[$column];
                        }
                        fputcsv($fp, $temRow);
                    }
                }

                $offset += $limit;
                unset($data);//释放变量的内存
                unset($temRow);//释放变量的内存
                //刷新输出缓冲到浏览器
                ob_flush();
                flush();//必须同时使用 ob_flush() 和flush() 函数来刷新输出缓冲。
            } while ($count === $limit && $finish === false);
            fclose($fp);
        }
    }
}